#!/bin/bash

#############################################################################################
# 用途: 清理 Docker Registry 镜像
# 作者: 丁辉
# 更新时间: 2024-05-08
#############################################################################################

# 配置全局环境变量
function Init_env() {
    # 定义颜色
    RED='\033[0;31m'
    NC='\033[0m'
    GREEN='\033[32m'
    YELLOW='\033[33m'

    # 定义时间格式
    TIME="+%Y-%m-%d %H:%M:%S"

    # 定义函数 send_info
    function SEND_INFO() {
        info=$1
        echo -e "${GREEN}$(date "$TIME") INFO: $info${NC}"
    }

    # 定义函数 send_warn
    function SEND_WARN() {
        warn=$1
        echo -e "${YELLOW}$(date "$TIME") WARN: $warn${NC}"
    }

    # 定义函数 send_error
    function SEND_ERROR() {
        error=$1
        echo -e "${RED}$(date "$TIME") ERROR: $error${NC}"
    }
}

# --help 帮助信息
function HELP_BINARY(){
    echo "Options:"
    echo "  -h, --help              显示此帮助信息"
    echo "  -v, --version           显示当前脚本版本号"
    echo "  -u                      Registry用户"
    echo "  -p                      Registry密码"
    echo "  -r                      Registry访问地址"
    echo "  -k                      Registry保留镜像Tag数量"
    echo ""
    exit 0
}

Init_env

# 解析命令行参数
while getopts "hvu:p:r:k:" opt; do
    case $opt in
        h)
            HELP_BINARY
            ;;
        v)
            echo "v1.0.0"
            exit 0
        ;;
        u)
            REGISTRY_USER=$OPTARG
        ;;
        p)
            REGISTRY_PASSWORD=$OPTARG
        ;;
        r)
            REGISTRY_URL=$OPTARG
        ;;
        k)
            KEEP_COUNT=$OPTARG
        ;;
        ?)
            SEND_ERROR "参数配置错误,请查看帮助信息"
            HELP_BINARY
        ;;
    esac
done

# 设置默认的 KEEP_COUNT 值
if [ -z "$KEEP_COUNT" ]; then
    KEEP_COUNT=0
fi

# 检查是否提供了所有必要的参数
if [ -z "$REGISTRY_USER" ] || [ -z "$REGISTRY_PASSWORD" ] || [ -z "$REGISTRY_URL" ] || [ -z "$KEEP_COUNT" ]; then
    SEND_ERROR "缺少必要的参数,请查看帮助信息"
    HELP_BINARY
fi

# 检查依赖是否存在
SEND_INFO "正在检查 jq 是否存在"
if ! which jq > /dev/null 2>&1; then
    SEND_ERROR "请安装 jq 工具: yum -y install jq 或 apt -yinstall jq"
fi

# 获取所有的 repositories
REPOSITORIES=$(curl -s -u "$REGISTRY_USER:$REGISTRY_PASSWORD" "http://$REGISTRY_URL/v2/_catalog" | jq -r '.repositories[]')

# 遍历每个 repository
for REPO in $REPOSITORIES; do
    # 获取当前 repository 的所有 tags
    TAGS=$(curl -s -u "$REGISTRY_USER:$REGISTRY_PASSWORD" "http://$REGISTRY_URL/v2/$REPO/tags/list" | jq -r '.tags[]? // empty' | sort -r)
    # 仓库 $REPO 没有检测到Tag, 跳过"
    if [ -z "$TAGS" ]; then
        continue
    fi
    KEEP_TAG=$(echo "$TAGS" | head -n $KEEP_COUNT)  # 保留列表中的Tag

    # 删除除了 KEEP_TAG 之外的所有其他 tags
    for TAG in $TAGS; do
        if [[ "$TAG" != "$KEEP_TAG" ]]; then
            # 首先获取这个 tag 的 digest
            DIGEST=$(curl -IsSH 'Accept: application/vnd.docker.distribution.manifest.v2+json' -u "$REGISTRY_USER:$REGISTRY_PASSWORD" "http://$REGISTRY_URL/v2/$REPO/manifests/$TAG" | grep 'Docker-Content-Digest:' | awk '{print $2}' | tr -d '\r')
            # 发送删除请求到 Docker Registry
            curl -s -u "$REGISTRY_USER:$REGISTRY_PASSWORD" -X DELETE "http://$REGISTRY_URL/v2/$REPO/manifests/$DIGEST"
        fi
    done
done
